package com.whz.gateway.configure.sensitive;

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.csp.sentinel.property.SimplePropertyListener;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Sets;
import com.whz.gateway.common.util.GatewayJsonUtils;
import com.whz.governance.sensitive.SensitiveEnum;
import com.whz.governance.sensitive.SensitiveNacosConfig;
import com.whz.governance.sensitive.utils.ConfigLoaderUtils;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author whz
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class IpSensitiveService implements ApplicationRunner {

    private final AtomicBoolean onlyOnce = new AtomicBoolean(false);

    private final Set<String> blackIps = Sets.newConcurrentHashSet();

    private final NacosConfigManager nacosConfigManager;

    private final SensitiveNacosConfig sensitiveNacosConfig;

    public boolean matchBlackIp(String remoteIp) {
        boolean contains = blackIps.contains(remoteIp);
        if (contains) {
            log.info("remoteIp:[{}] match Black-IP-LIST.", remoteIp);
        }
        return contains;
    }

    @SneakyThrows
    @Override
    public void run(ApplicationArguments args) {
        if (onlyOnce.compareAndSet(false, true)) {
            log.info("从nacos订阅ip黑名单...");
            String config = nacosConfigManager.getConfigService().getConfig(SensitiveEnum.IP_BLACK.getDataId(),
                    sensitiveNacosConfig.getGroupId(),
                    TimeUnit.SECONDS.toMicros(2));
            if (StringUtils.isNotBlank(config)) {
                try {
                    blackIps.addAll(JSON.parseArray(config, String.class));
                } catch (Exception ignored) {
                    log.error("存在非法的 black-list格式ip");
                }
            }
            log.info("读取当前黑名单配置:{}", blackIps);
            ConfigLoaderUtils.loadIpBlackListChanged(new SimplePropertyListener<List<String>>() {
                @Override
                public void configUpdate(List<String> value) {
                    log.info("nacos blacklist:{}", value);
                    if (Objects.nonNull(value)) {
                        blackIps.clear();
                        blackIps.addAll(value);
                        log.info("Receive changed BLACK-IP-LIST:\n {}", GatewayJsonUtils.toJson(value));
                    }
                }
            });
        }
    }
}